﻿#include "spectrometercontrol.h"
#include <QDebug>

#include "waitutils.h"
#include "devicemanager.h"
#include "cmosspectrometer.h"
#include "IdeaopticsSpectroMeter.h"
#include "AvsSpectroMeterUtils.h"

QMutex _mutex;

SpectroMeterControl::SpectroMeterControl()
{
//    for(auto item:DeviceManager::Instance().GetAllDevice())
//    {
//        BaseSpectroMeter* meter=dynamic_cast<BaseSpectroMeter*>(item);
//        if(meter!=nullptr)
//        {
//            AddSpectroMeter(meter);
//        }
//    }
}

SpectroMeterControl::~SpectroMeterControl()
{
    ClearAllMeter();
}

BaseSpectroMeter * SpectroMeterControl::CreateMeter()
{
    BaseSpectroMeter *meter=nullptr;
    if(_obj["EnumType"].toString()=="BaseSpectroMeter")
    {
        meter=new BaseSpectroMeter();
    }
    else if (_obj["EnumType"].toString()=="IdeaopticsSpectroMeter")
    {
        meter=new IdeaopticsSpectroMeter();
    }
    else
    {
        meter=new CMOSSpectroMeter();
    }

    return meter;
}

void SpectroMeterControl::EnumSpectroMeter(QList<AvsInfo> &avsInfos)
{
    if(_obj["EnumType"].toString()=="BaseSpectroMeter")
    {
        BaseSpectroMeter::EnumSpectro(avsInfos);
    }
    else if (_obj["EnumType"].toString()=="IdeaopticsSpectroMeter")
    {
        IdeaopticsSpectroMeter::EnumSpectro(avsInfos);
    }
    else
    {
        CMOSSpectroMeter::EnumSpectro(avsInfos);
    }
//    meter->EnumSpectro(avsInfos);
//    delete meter;
}

const AvsMeasPara SpectroMeterControl::GetMeasPara()
{
    AvsMeasPara ret;
    ret.integrationTime=_other["IntegrationTime"].toDouble();
    ret.integrationDelay=_other["IntegrationDelay"].toInt();
    ret.NrAverages=_other["AverageTimes"].toInt();
    ret.triggerMode=_other["TriggerMode"].toInt();
    _allSpectroMeters.at(0)->GetMeasParam(ret);
    return ret;
}

bool SpectroMeterControl::StartMeasure()
{

    for(int i=1;i<_allSpectroMeters.count();i++)
    {
        _allSpectroMeters.at(i)->StartMeasure();
    }
    _allSpectroMeters.at(0)->StartMeasure();

    return true;
}

bool SpectroMeterControl::ClearData()
{
    QMutexLocker locker(&_mutex);
    _receiveDataNew.clear();
    return true;
}

bool SpectroMeterControl::SetTriggerMode(bool isSoft)
{
    if(isSoft)
    {
        for(int i=0;i<_allSpectroMeters.count();i++)
        {
            auto item=_allSpectroMeters.at(i);
            AvsMeasPara p;
            item->GetMeasParam(p);
            p.triggerMode=0;
            p.triggerSource=1;
            item->SetMeasureParam(p);
        }
    }
    else
    {
        qDebug()<<__FUNCTION__<<__LINE__;
        for(int i=0;i<_allSpectroMeters.count();i++)
        {
            qDebug()<<__FUNCTION__<<__LINE__<<i;
            auto item=_allSpectroMeters.at(i);
            AvsMeasPara p;
            item->GetMeasParam(p);
            p.triggerMode=1;
            if(i==0)
            {
                p.triggerSource=0;
                p.isMasterChannel=true;
            }
            else
            {
                p.triggerSource=1;
                p.isMasterChannel=false;
            }
            item->SetMeasureParam(p);
        }
    }
    return true;
}

bool SpectroMeterControl::StopMeasure()
{
    return true;
}

void SpectroMeterControl::ClearAllMeter()
{
    for(auto meter:_allSpectroMeters)
    {
        meter->disconnect();
        delete meter;
    }
    _allSpectroMeters.clear();
    _allSpectroMeterSNs.clear();
}

QList<BaseSpectroMeter *> SpectroMeterControl::UpdateAllMeter()
{
    //清楚内存中所有光谱仪
    ClearAllMeter();
    QList<BaseSpectroMeter*> ret;
    QList<AvsInfo> avsInfos;
    EnumSpectroMeter(avsInfos);
    for(auto item:avsInfos)
    {
        BaseSpectroMeter* meter=CreateMeter();
        QJsonObject obj=_other;
        obj["Serial"]=item.serial;
        obj["PCIP"]=item.pcIP;
        obj["PCPort"]=item.pcPort;
        obj["SpectrometerIP"]=item.spectrometerIP;
        obj["SpectrometerPort"]=item.spectrometerPort;
        qDebug()<<obj;
        meter->SetOtherConfig(obj);
        if(meter->OpenSpectro())
        {
            //这里使用别的连接方式无法接受返回信号
            connect(meter,&BaseSpectroMeter::OnDataReceive,this,&SpectroMeterControl::OnDataReveiveHandle,Qt::DirectConnection);
            ret.append(meter);
        }
        else
        {
            meter->deleteLater();
        }
    }
    std::sort(ret.begin(),ret.end(),[](BaseSpectroMeter *meter1, BaseSpectroMeter *meter2) {
        return meter1->GetLambda().first() < meter2->GetLambda().first();
    });

    int count = ret.count();
    for (int i = 0; i < count; i++)
    {
        _allSpectroMeterSNs.push_back(ret.at(i)->GetSpectrumInfo().serilID);
    }

    _allSpectroMeters.append(ret);
    return ret;
}

QList<SpectroInfoTag> SpectroMeterControl::GetSpectroMeterInfo()
{
    QList<SpectroInfoTag> ret;
    for(auto item:_allSpectroMeters)
    {
        ret.append(item->GetSpectrumInfo());
    }
    return ret;
}

AvsMeasResultList SpectroMeterControl::ReadData(bool removeBase)
{
    int count = _allSpectroMeters.count();
    //当接收到的光谱数量小于光谱仪总数量时，保持等待
    while(_receiveDataNew.count() != count)
    {
        WaitUtils::WaitMs(1);
        if (_receiveDataNew.count() > count)
        {
            return _receiveDataNew;
        }
    }
//    std::sort(_receiveDataNew.begin(),_receiveDataNew.end(),[](const AvsMeasResult &list1, const AvsMeasResult &list2) {
//        if (list1.resultData.isEmpty() || list2.resultData.isEmpty()) {
//            // 处理空 resultData 的情况，比如返回 false 或抛出异常
//            return false;
//        }

//        return list1.resultData.first().x() <= list2.resultData.first().x();
//    });

    if (count > 1)
    {
        QMap<QString, AvsMeasResult> serialToResultMap;
        QMutexLocker locker(&_mutex);
        for (int i = 0; i < _receiveDataNew.size(); i++)
        {
            if (_receiveDataNew.at(i).SerialId.isEmpty())
            {
                qWarning() << "SerialId is empty at index: " << i;
            }
            else
            {
                serialToResultMap[_receiveDataNew.at(i).SerialId] = _receiveDataNew.at(i);
            }
        }
//        for (int i = 0; i < _receiveDataNew.count(); i++)
//        {
//            serialToResultMap[_receiveDataNew.at(i).SerialId] = _receiveDataNew.at(i);
//        }

        // 根据 _allSpectroMeterSNs 的顺序，重新构建 _receiveDataNew
        AvsMeasResultList sortedReceiveDataNew;
        for (const QString& sn : _allSpectroMeterSNs)
        {
            if (serialToResultMap.contains(sn))
            {
                sortedReceiveDataNew.append(serialToResultMap[sn]);
            }
            else
            {
                qWarning() << "Serial ID" << sn << "not found in receiveDataNew";
            }
        }

        _receiveDataNew = sortedReceiveDataNew;
    }
    return _receiveDataNew;
}

BaseSpectroMeter *SpectroMeterControl::GetSpectroMeter(int index)
{
    if(index>_allSpectroMeters.count()-1)
    {
        throw QString("获取光谱仪错误");
    }

    return _allSpectroMeters.at(index);
}

SpectroMeterControl &SpectroMeterControl::Instance()
{
    static SpectroMeterControl instance;
    return instance;
}

bool SpectroMeterControl::Stop()
{
    for(auto item:_allSpectroMeters)
    {
        if(!item->Stop())
        {
            return false;
        }
    }
    return true;
}

bool SpectroMeterControl::SoftTrigger()
{
    for(auto item:_allSpectroMeters)
    {
        if(!item->SoftTrigger())
        {
            return false;
        }
    }
    return true;
}

void SpectroMeterControl::OnDataReveiveHandle(AvsMeasResult data)
{
    QMutexLocker locker(&_mutex);
    qDebug() << QString("%1 %2").arg(QDateTime::currentDateTime().toString("hh:mm:ss.zzz")).arg(data.SerialId);

    // 检查 _receiveDataNew 中是否存在相同 SerialId 的数据
    bool isDuplicate = false;
    for (const auto& item : _receiveDataNew) {
        if (item.SerialId == data.SerialId) {
            isDuplicate = true;
            break;
        }
    }

    // 如果没有重复且 _receiveDataNew 的数量小于 _allSpectroMeters 的数量，则添加数据
    if (!isDuplicate && _receiveDataNew.count() < _allSpectroMeters.count()) {
        _receiveDataNew.append(data);
    }
}

//void SpectroMeterControl::SetOtherConfig(QJsonObject config)
//{
//    //设置积分时间 设备类型 采集谱图数量
//    _=config;
//}
